<?php
/**
 * FastApp.
 * 12/20/24
 * @Author deepsea159
 * @Contact telegram:deepsea159
 */

namespace App\Fastapp\Api\Service\Account;

use App\Fastapp\Api\Service\BaseService;
use App\Fastapp\Model\AccountInviteLevel;
use App\Fastapp\Model\AccountWalletLog;
use App\Fastapp\Model\FastappChannelAgentSettlement;
use Carbon\Carbon;
use Hyperf\Database\Model\Builder;

class AgentService extends BaseService
{
    public function team(): array
    {
        $uid = get_uid();
        $query = $this->getQuery($uid);
        $team_num = $query->count();
        $level1_num = AccountInviteLevel::query()->where(['parent_id' => $uid])->count();
        return [
            'team_num' => $team_num,
            'level1_num' => $level1_num,
        ];
    }

    public function income(): array
    {
        $uid = get_uid();
        $income = FastappChannelAgentSettlement::query()
            ->selectRaw('sum(amount) as amount,status')
            ->where(['user_id' => $uid])->groupBy('status')
            ->pluck('amount', 'status')->toArray();
        $total_withdrawal = AccountWalletLog::query()->where(['user_id' => $uid, 'type' => AccountWalletLog::WITHDRAWAL])->sum('amount');
        return [
            'total_income' => $income[0] ?? 0,
            'total_withdrawal' => $total_withdrawal,
            'total_withdrawal_pending' => $income[1] ?? 0,
        ];
    }

    public function newUserCount(array $param = []): array
    {
        $uid = get_uid();
        $query = $this->getQuery($uid);
        $start_at = Carbon::now()->subDays(6);
        $end_at = Carbon::now()->addDay();
        $bwt = [$start_at->toDateString(), $end_at->toDateString()];
        $res = $query->whereBetween('created_at', $bwt)
            ->get(['created_at']);
        $days = [];
        while ($start_at->diffInDays($end_at)) {
            $days[$start_at->toDateString()] = 0;
            $start_at->addDay();
        }
        foreach ($res as $item) {
            $days[$item->created_at->toDateString()]++;
        }
        return $days;
    }

    public function rechargeCount(): array
    {
        $uid = get_uid();
        $query = $this->getQuery($uid)->from('account_invite_level as a')
            ->leftJoin('account_recharge as b', 'a.user_id', '=', 'b.user_id')
            ->where('b.status', '=', 1);
        $recharge_num = (clone $query)->groupBy('a.user_id')->pluck('a.user_id')->count();
        $total_recharge = $query->sum('amount');
        $day30_recharge = $query->whereBetween('a.created_at', [Carbon::now()->subDays(29)->toDateString(), Carbon::now()->addDay()->toDateString()])->sum('amount');
        $day_recharge = $query->whereBetween('a.created_at', [Carbon::now()->toDateString(), Carbon::now()->addDay()->toDateString()])->sum('amount');

        $query = $this->getQuery($uid)->from('account_invite_level as a')
            ->leftJoin('account_withdrawal as b', 'a.user_id', '=', 'b.user_id')
            ->where('b.status', '=', 1);
        $withdrawal_num = (clone $query)->groupBy('a.user_id')->pluck('a.user_id')->count();
        $total_withdrawal = $query->sum('amount');
        $day30_withdrawal = $query->whereBetween('a.created_at', [Carbon::now()->subDays(29)->toDateString(), Carbon::now()->addDay()->toDateString()])->sum('amount');
        $day_withdrawal = $query->whereBetween('a.created_at', [Carbon::now()->toDateString(), Carbon::now()->addDay()->toDateString()])->sum('amount');

        return [
            'total_recharge' => $total_recharge,
            'day30_recharge' => $day30_recharge,
            'day_recharge' => $day_recharge,
            'total_withdrawal' => $total_withdrawal,
            'day30_withdrawal' => $day30_withdrawal,
            'day_withdrawal' => $day_withdrawal,
            'avg_recharge' => $total_recharge ? bcadd((string)($total_recharge / $recharge_num), '0', 2) : 0,
            'avg_withdrawal' => $withdrawal_num ? bcadd((string)($total_withdrawal / $withdrawal_num), '0', 2) : 0,
        ];
    }

    public function getQuery(int $uid): Builder
    {
        $md = AccountInviteLevel::query()->where(['user_id' => $uid])->first();
        if ($md) $link = $md->link . ',' . $uid; else $link = $uid . '|';
        return AccountInviteLevel::query()->where('link', 'like', $link . '%');
    }
}